package net.wofly.sale.order.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.transaction.Transactional;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import net.wofly.flow.dto.FormPropertyDto;
import net.wofly.flow.service.IWorkFlowService;
import net.wofly.framework.util.ResultCode;
import net.wofly.framework.util.ReturnBean;
import net.wofly.sale.order.domain.ReturnSales;
import net.wofly.sale.order.service.IReturnSalesFlowService;
import net.wofly.sale.order.service.IReturnSalesService;
import net.wofly.sale.order.util.ReturnSalesStatus;

@Service("iReturnSalesFlowService")
@Transactional
public class ReturnSalesFlowService implements IReturnSalesFlowService {
	private final String processDefKey = "returnSales" ; 
	
	@Autowired
	IReturnSalesService iReturnSalesService ;
	@Autowired
	IWorkFlowService iWorkFlowService ;
	@Autowired
	ProcessEngine processEngine ;
	@Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    FormService formService ;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private IdentityService identityService;

	@Override
	public ReturnBean<String> startWorkflow(String userId, String returnSalesID, Map<String, Object> variables) {
		long l = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(returnSalesID).count() ;
		if (l>0) {
			return new ReturnBean<>(672 , "当前业务数据:'"+ returnSalesID +"'己提交工作流，不可重复提交。");
		} 
		
        // 用来设置启动流程的人员ID，引擎会自动把用户ID保存到activiti:initiator中
        identityService.setAuthenticatedUserId(userId);
        
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(this.processDefKey, returnSalesID, variables) ;
        
        if (null==processInstance) {
        		return new ReturnBean<>(673,"工作流启动出错！") ; 
        }
        
        /**
         * 流程启动后，下一个节点是发起人节点时，流程启动设置为任务的执行人，同时自动执行此任务
         */
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
        if (task!=null) {
	        	if (task.getName().equals("流程发起人")) {
	        		processEngine.getTaskService().setAssignee(task.getId(), userId);
	        		Map<String ,Object> mapFlow = new HashMap<>() ;
	        		mapFlow.put("flow_opt", "20") ;
	        		taskService.complete(task.getId() ,mapFlow);
	        		task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
	        }
        }
        
        ReturnSales returnSales = iReturnSalesService.findOne(returnSalesID) ;
        
        returnSales.setProcessDefKey(this.processDefKey);
        returnSales.setProcessInsID(processInstance.getId());
        returnSales.setStatus(ReturnSalesStatus.待审核.getValue());
        returnSales.setTaskID(task.getId());
        returnSales.setTaskName(task.getName());
        
        iReturnSalesService.save(returnSales) ;
        
        return new ReturnBean<>(0,"工作流启动成功" ,processInstance.getProcessInstanceId()) ; 
	}

	@Override
	public List<ReturnSales> findToDoList(String userId) {
		List<Task> tasks = new ArrayList<>();
		List<Task> todoList = new ArrayList<>();
		
		// 根据当前人的ID查询
		todoList = taskService.createTaskQuery().processDefinitionKey(this.processDefKey).taskAssignee(userId).orderByTaskCreateTime().desc().list();
		tasks.addAll(todoList);
		List<String> processInsIDs = new ArrayList<>() ;
        
        // 根据流程的业务ID查询实体并关联
        for (Task task : tasks) {
        		processInsIDs.add(task.getProcessInstanceId());
        }
        
        List<ReturnSales> ReturnSaleses = iReturnSalesService.findByProcessInsIDIn(processInsIDs) ;
        for(ReturnSales returnSales:ReturnSaleses) {
        		iReturnSalesService.translateReturnSalesInfo(returnSales) ;
        }
        
        //TODO 获取任务中相关信息
        
        return ReturnSaleses ;
	}

	@Override
	public ReturnBean<String> complete(String userID, String taskID, Map<String, String[]> mapRequest) {
Task task = taskService.createTaskQuery().taskId(taskID).singleResult();
		
		if (null==task) {
			return new ReturnBean<>(610,"没有此任务或任务己执行完成！") ;
		}
		
		if (!StringUtils.equals(task.getAssignee(), userID)) {
			return new ReturnBean<>(603,"指定任务的办理人非当前用户，不能完成任务！") ;
		}
		
		List<FormPropertyDto>  fpds = iWorkFlowService.taskFormProperty( task) ;
		
		ReturnBean<Map<String ,Object>> rb = iWorkFlowService.getFlowVarMap(fpds , mapRequest) ;
		if(!rb.getCode().equals(ResultCode.SUCCESS)) {
			return new ReturnBean<>(rb.getCode(),rb.getMsg()) ;
		}
		
		Map<String ,Object> mapFlow = rb.getResult();
		
		String businessStatus = iWorkFlowService.getBsuinessStatus(mapFlow) ;
		
		iWorkFlowService.addComment( task ,mapFlow ) ;
		
		taskService.complete(taskID, mapFlow);
		
		// 完成任务后，判断下个节点是否为流程发起人节点， 如果为流程发起人节点且没有作务代理人时，系统将上次代理人设置到任务节点上
		Task nextTask = taskService.createTaskQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
        if (nextTask!=null) {
	        	if (nextTask.getName().equals("流程发起人")) {
	        		processEngine.getTaskService().setAssignee(nextTask.getId(), iWorkFlowService.getInitiatorAssignee(nextTask.getProcessInstanceId()));
	        }
        }
        
        ReturnSales returnSales  = iReturnSalesService.findByProcessInsID(task.getProcessInstanceId()) ;
        
        returnSales.setStatus(Integer.valueOf(businessStatus));
        if (null != nextTask) {
		    	returnSales.setTaskID(nextTask.getId());
		    	returnSales.setTaskName(nextTask.getName());
        }else {
        		returnSales.setIsFinish(1);
        }
        
        iReturnSalesService.save(returnSales) ;
        
		return new ReturnBean<>(0, "工作流执行完成" ) ;
	}

	@Override
	public ReturnBean<ReturnSales> getReturnSalesForFlow(String returnSalesID) {
		ReturnSales returnSales = iReturnSalesService.findOne(returnSalesID) ;
		
		if (returnSales==null) {
			return new ReturnBean<>(611,"业务工作流实例不存在") ;
		}
		
		if (returnSales.getTaskID() == null) {
			return new ReturnBean<>(612,"业务工作流任务不存在") ;
		}
		
		Task task = taskService.createTaskQuery().taskId(returnSales.getTaskID()).singleResult();
		if (null == task) {
			return new ReturnBean<>(0,"获取成功" ,returnSales ) ; 
		}
		
		List<FormPropertyDto> formPropertyDtos = iWorkFlowService.taskFormProperty( task) ;
		
		List<Comment> comments =  taskService.getProcessInstanceComments(returnSales.getProcessInsID()) ;
		returnSales.setComments(comments);
		returnSales.setFormPropertyDtos(formPropertyDtos);
		
		iReturnSalesService.translateReturnSalesInfo(returnSales);
		
		return new ReturnBean<>(0, "获取工作流信息成功" , returnSales) ;
	}

	

}
